package com.szsky.sky.config;

import com.szsky.sky.utils.AESUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class EncryptedPropertySourcePostProcessor implements PropertySourceLoader {

    private static final String START_ENCRYPTED_PREFIX = "RJ(";
    private static final String END_ENCRYPTED_PREFIX = ")";

    @Override
    public String[] getFileExtensions() {
        return new String[]{"yml", "yaml", "properties"};
    }

    @Override
    public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
        if (!resource.exists()) {
            return null;
        }

        // 使用Spring Boot内置的配置文件解析器
        OriginTrackedMapPropertySource originalSource = (OriginTrackedMapPropertySource) new YamlPropertySourceLoader().load(name, resource).get(0);
        Map<String, Object> decryptedProperties = new HashMap<>();
        for (String propertyName : originalSource.getPropertyNames()) {
            Object value = originalSource.getProperty(propertyName);
            if (value instanceof String) {
                String strValue = (String) value;
                if (strValue.startsWith("RJ(") && strValue.endsWith(")")) {
                    String encryptedValue = strValue.substring(START_ENCRYPTED_PREFIX.length(), strValue.length() - 1);
//                    String encryptedValue = strValue.substring(START_ENCRYPTED_PREFIX.length(), END_ENCRYPTED_PREFIX.length());
                    String decryptedValue = null;
                    try {
                        decryptedValue = AESUtil.decrypt(encryptedValue);
                    } catch (Exception e) {
                        log.error("decrypt fail：{}", e);
                    }
                    decryptedProperties.put(propertyName, decryptedValue);
                } else {
                decryptedProperties.put(propertyName, strValue);
                }
            } else {
                decryptedProperties.put(propertyName, value);
            }
        }
        MapPropertySource propertySource = new MapPropertySource(name, decryptedProperties);
        List<PropertySource<?>> list = new ArrayList<>();
        list.add(propertySource);
        return list;
    }
}
